package org.lbm.flow.node;

import org.lbm.flow.agent.Agent;
import org.lbm.flow.agent.AgentResult;
import org.lbm.flow.context.FlowContext;
import org.lbm.flow.exception.FlowException;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 智能体节点
 * 封装智能体执行逻辑的节点
 *
 * @author insist
 * @since 2025-08-01
 */
public class AgentNode extends BaseNode {

    public AgentNode(String id, String name, String description, Agent agent) {
        super(id, name, "agent", description);
        this.agent = agent;
    }

    public AgentNode(String id, String name, String description) {
        super(id, name, "agent", description);
    }

    @Override
    public NodeResult execute(FlowContext context) {
        if (agent == null) {
            return NodeResult.failed(id, "智能体未设置");
        }

        if (!agent.isAvailable()) {
            return NodeResult.skipped(id, "智能体不可用");
        }

        long startTime = System.currentTimeMillis();
        System.out.println("开始执行节点: " + id + " (智能体: " + agent.getName() + ")");

        try {
            // 检查是否已经执行过
            if (isCompleted(context)) {
                System.out.println("节点 " + id + " 已经完成，跳过执行");
                return NodeResult.skipped(id, "节点已经完成");
            }

            if (isFailed(context)) {
                System.out.println("节点 " + id + " 已经失败，跳过执行");
                return NodeResult.failed(id, "节点已经失败");
            }

            // 执行智能体
            AgentResult agentResult = executeAgentWithTimeout(context);

            // 记录执行时间
            long executionTime = System.currentTimeMillis() - startTime;

            // 创建节点结果，使用节点级别的执行时间
            NodeResult nodeResult = NodeResult.fromAgentResult(id, agentResult)
                    .withExecutionTime(executionTime);

            // 根据结果标记节点状态
            if (nodeResult.isSuccess()) {
                markCompleted(context);
                System.out.println("节点 " + id + " 执行成功，耗时: " + executionTime + "ms");
            } else {
                markFailed(context);
                System.err.println("节点 " + id + " 执行失败: " + nodeResult.getMessage());
            }

            return nodeResult;

        } catch (Exception e) {
            long executionTime = System.currentTimeMillis() - startTime;
            System.err.println("节点 " + id + " 执行异常: " + e.getMessage());
            e.printStackTrace();
            markFailed(context);
            return NodeResult.failed(id, "执行异常: " + e.getMessage(), e)
                    .withExecutionTime(executionTime);
        }
    }

    /**
     * 带超时的智能体执行
     */
    private AgentResult executeAgentWithTimeout(FlowContext context) throws Exception {
        CompletableFuture<AgentResult> future = CompletableFuture.supplyAsync(() -> {
            try {
                return agent.execute(context);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        try {
            return future.get(timeout, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            future.cancel(true);
            return AgentResult.timeout("执行超时 (" + timeout + "ms)");
        } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            throw new FlowException("智能体执行失败", cause);
        }
    }

    @Override
    public boolean canExecute(FlowContext context) {
        if (!super.canExecute(context)) {
            return false;
        }

        // 检查智能体是否可用
        if (agent != null && !agent.isAvailable()) {
            return false;
        }

        return true;
    }

    /**
     * 获取智能体
     */
    public Agent getAgent() {
        return agent;
    }

    /**
     * 设置智能体
     */
    public void setAgent(Agent agent) {
        this.agent = agent;
    }
}
